package com.hpc.Service.Impl;

import Utils.JSONUtil;
import Utils.StringHandlerUtils;
import com.alibaba.fastjson.JSON;
import com.hpc.Service.articleService;
import com.hpc.Service.OpenFeignService1;
import entity.article;
import entity.comment;
import entity.systemConstant;
import entity.user;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class articleServiceImpl implements articleService {
    @Resource
    private com.hpc.mapper.articleMapper articleMapper;
    @Resource
    private com.hpc.mapper.commentMapper commentMapper;
    @Resource
    private OpenFeignService1 openfeignService;
    @Resource
    private RedisTemplate redisTemplate;
    public static final Integer ADFLAG=3;
    public article findById(String articleId) {
        article byId = articleMapper.findById(articleId);
        return byId;
    }

    @Override
    public List<article> getRecommendArticles(List<String> titles) {
        List<article> recommendArticles=new ArrayList<>();
        for (String title : titles) {
             List<article> recommendArticlesTemp = articleMapper.getRecommendArticles(title);
             recommendArticles.addAll(recommendArticlesTemp);
        }
        if (recommendArticles.size()>5){
//            Map entries = redisTemplate.opsForHash().entries(systemConstant.LIKESOFARTICLE);
//            List<Map.Entry<String,String>> entryList=new ArrayList<>(entries.entrySet());
//            Collections.sort(entryList, new Comparator<Map.Entry<String, String>>() {
//                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
//                    return Integer.valueOf(o2.getValue()).compareTo(Integer.valueOf(o2.getValue())); // 按照 value 的大小进行降序排序
//                }
//            });
            Collections.sort(recommendArticles,Comparator.comparing(article::getHot));
            List<article> articles = recommendArticles.subList(0, 4);
            return articles;
        }else {
         return recommendArticles;
        }
    }

    @Override
    public void hotweekendly() {
        List<article> hotweekendly = articleMapper.hotweekendly();
        if (hotweekendly.size()>5){
            for (int i = 0; i < 5; i++) {
                systemConstant.HOTWEEKENDLY.set(i,hotweekendly.get(i).getSerial());
            }
        }else {
            for (int i = 0; i < hotweekendly.size(); i++) {
                systemConstant.HOTWEEKENDLY.set(i,hotweekendly.get(i).getSerial());
            }
        }
    }

    @Override
    public List<article> gethotTop5() {
        List<article> articles = articleMapper.gethotTop5(systemConstant.HOTWEEKENDLY);
        return articles;
    }
    /**
     * @author: Liujd
     * @createTime: 2023/5/16 22:55
     * @description: readArticle,返回文章的详细内容，文章作者的信息，文章所有的评论，文章喜欢数
     * @param:[articleId, userid]
     * @return:java.util.Map<java.lang.String,java.lang.String>
     */
    @Override
    public Map<String,String> readArticle(String articleId,String userid) {
        article article = articleMapper.findById(articleId);
        String userInfoByArticleId = openfeignService.getUserInfoByArticleId(articleId);
        user userOfArticle = JSON.parseObject(userInfoByArticleId, user.class);
        List<comment> commentsByArticleId = commentMapper.getCommentsByArticleId(articleId);
        ArrayList<String> userIds =new ArrayList<>();
        for (comment comment : commentsByArticleId) {
            userIds.add(comment.getUser_id());
        }
        String userIdsJson = JSONUtil.toJSONString(userIds);
        String userInfoOfComment = openfeignService.getUserInfoOfComment(userIdsJson);
        List<String> imagesUrl=new ArrayList<>();
        String keyName=articleId+"_imageUrls";
        if (redisTemplate.hasKey(keyName)){
            imagesUrl=redisTemplate.opsForList().range(keyName,0,-1);
        }
        int likesCount=0;
        if(redisTemplate.opsForHash().hasKey(systemConstant.LIKESOFARTICLE,articleId)){
            likesCount = (Integer) redisTemplate.opsForHash().get(systemConstant.LIKESOFARTICLE, articleId);
        }else {
        }
        int commentsCount = commentMapper.getCommentsCount(articleId);
        Map<String,String> infos=new HashMap<>();
        infos.put("userInfoOfArticle",userInfoByArticleId);
        if (redisTemplate.hasKey(userid+"_follow")){
            boolean flag=true;
            List<String> range = redisTemplate.opsForList().range(userid + "_follow", 0, -1);
            for (String s : range) {
                if (s.equalsIgnoreCase(userOfArticle.getSerial())){
                    infos.put("isFollowed","1");
                    flag=false;
                    break;
                }
            }
            if (flag){
                infos.put("isFollowed","0");
            }
        }else {
            infos.put("isFollowed","0");
        }
        if (redisTemplate.hasKey(userid+"_personallike")){
            List<article> range = redisTemplate.opsForList().range(userid + "_personallike", 0, -1);
            if (range.size()!=0){
                for (entity.article article1 : range) {
                    if (article1.getSerial().equalsIgnoreCase(articleId)){
                        infos.put("isliked","1");
                    }
                }
            }else {
                infos.put("isliked","0");
            }
        }else {
            infos.put("isliked","0");
        }

        infos.put("allcomment", JSONUtil.toJSONString(commentsByArticleId));
        infos.put("userInfoOfComment",userInfoOfComment);
        infos.put("imagesUrl",JSONUtil.toJSONString(imagesUrl));
        infos.put("likesCount",String.valueOf(likesCount));
        infos.put("commentsCount",String.valueOf(commentsCount));
        infos.put("article",JSONUtil.toJSONString(article));
        return infos;
    }

    @Override
    public int addComment(String articleId, String userId, String content) {
        comment comment = new comment();
        comment.setSerial(UUID.randomUUID().toString());
        comment.setArticle_id(articleId);
        comment.setUser_id(userId);
        comment.setContent(content);
        comment.setCommentTime(new Date());
        int flag = commentMapper.addComment(comment);
        return flag;
    }

    @Override
    public boolean deleteArticle(String articleId) {
        int result1 = articleMapper.deleteArticle(articleId);
        deleteAricleAsyn(articleId);
        return result1==1?true:false;
    }

    @Override
    public List<comment> getCommentsByArticleId(String articleId) {
        return commentMapper.getCommentsByArticleId(articleId);
    }

    @Override
    public List<article> allArticle(int type) {
        List<article> articles = articleMapper.allArticle(type);
//        //获取所有广告
//        List<article> ads = articleMapper.allArticle(ADFLAG);
//        //按热度降序排序
//        ads.sort(Comparator.comparing(article::getHot).reversed());
        //对获取的文章内容去除视频video、图片img标签
        articles.forEach(article -> {
            String s = StringHandlerUtils.stripHtmlTags(article.getContent());
            article.setContent(s);
        });
//        ads.forEach(article -> {
//            String s = StringHandlerUtils.stripHtmlTags(article.getContent());
//            article.setContent(s);
//        });
//        //将articles按5个拆分成多个小集合
//        List<List<article>> subLists = new ArrayList<>();
//        for (int i = 0; i < articles.size(); i += 5) {
//            List<article> tempList=new ArrayList<>();
//            tempList.addAll(articles.subList(i, Math.min(i + 5, articles.size())));
//            subLists.add(tempList);
//        }
////        往subLists中每个随机插入一条广告，从ads顺序取出，随机数取小集合中的0到集合长度
//        Iterator<List<article>> iterator = subLists.iterator();
//        int index=0;
//        List<article> result = new ArrayList<>();
//        while (iterator.hasNext()) {
//            List<article> subList = iterator.next();
//            List<article> articles1 = Collections.synchronizedList(subList);
//            if (!ads.isEmpty()){
//                int randomIndex = new Random().nextInt(subList.size());
//                if(index < ads.size()){
//                    articles1.add(randomIndex, ads.get(index));
//                }
//            }
//            result.addAll(articles1);
//            index++;
//        }
        //重新将subLists组合成一个大集合
//        List<article> result = new ArrayList<>();
//        subLists.forEach(result::addAll);
        return articles;
    }

    @Override
    public List<article> allArticleByUserId(String userId,boolean isNeedFilter) {
        List<article> articles = articleMapper.allArticleByUserId(userId);
        //文章content去除html元素标签
        if(isNeedFilter){
            articles.forEach(article -> {
                String s = StringHandlerUtils.stripHtmlTags(article.getContent());
                article.setContent(s);
            });
        }
        return articles;
    }

    @Override
    public List<article> searchByTitle(String title) {
        List<article> articles = articleMapper.searchByTitle(title);
        articles.forEach(article -> {
            String s = StringHandlerUtils.stripHtmlTags(article.getContent());
            article.setContent(s);
        });
        return articles;
    }

    @Override
    public boolean publish(String title, String content, String userId,String category,String username,String cover) {
        article article = new article();
        article.setSerial(UUID.randomUUID().toString());
        article.setTitle(title);
        article.setPublishTime(new Date());
        log.info(category);
        int articletype = Integer.valueOf(category);
        log.info(String.valueOf(articletype));
        article.setType(articletype);
        article.setContent(content);
        article.setUser_id(userId);
        article.setCover(cover);
        int i = articleMapper.addArticle(article);
        if (i != 0){
            infoUser(article,username);
            return true;
        }
        return false;
    }

    @Override
    public boolean modifyArticle(String articleId, String content, String title, int type,String cover) {
        int i = articleMapper.modifyArticle(content, title, type, articleId,cover);
        if (i!=0){
            return true;
        }
        return false;
    }

    @Async
    public void deleteAricleAsyn(String articleId){
        Set<String> keys = redisTemplate.keys("*_personallike");
        for (String key : keys) {
            if (redisTemplate.hasKey(key)){
                List<article> range = redisTemplate.opsForList().range(key, 0, -1);
                for (article article : range) {
                    if (article.getSerial().equalsIgnoreCase(articleId)){
                        redisTemplate.opsForList().remove(key,1,article);
                    }
                }
            }
        }
    }
    @Async
    public void infoUser(article article,String username){
        String user_id = article.getUser_id();
        Set<String> keys = redisTemplate.keys("*_follow");
        for (String key : keys) {
            List<String> range = redisTemplate.opsForList().range(key, 0, -1);
            if (range.size()!=0){
                for (String s : range) {
                    if (s.equalsIgnoreCase(user_id)){
                        String userId=key.substring(0,key.indexOf('_'));
                        String msg="您关注的"+username+"发布了新的文章："+article.getTitle();
                        String UUID= java.util.UUID.randomUUID().toString();
                        articleMapper.infoUser(UUID,userId,msg);
                    }
                }
            }
        }
    }
//    //提取html文本中的纯文本
//    private  String stripHtmlTags(String html) {
//        Pattern pattern = Pattern.compile("<[^>]*>");
//        Matcher matcher = pattern.matcher(html);
//        String strippedHtml = matcher.replaceAll("");
//        // 去除特殊字符
//        strippedHtml = strippedHtml.replaceAll("&nbsp;", "");
//        strippedHtml = strippedHtml.replaceAll("&gt;", "");
//        strippedHtml = strippedHtml.replaceAll("\\n", "");
//        return strippedHtml;
//    }
}
